home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / atc / grammar.y < prev    next >
Text File  |  1995-05-03  |  8KB  |  390 lines

  1. /*-
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Ed James.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. /*
  38.  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
  39.  *
  40.  * Copy permission is hereby granted provided that this notice is
  41.  * retained on all partial or complete copies.
  42.  *
  43.  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
  44.  */
  45.  
  46. %token <ival>    HeightOp
  47. %token <ival>    WidthOp
  48. %token <ival>    UpdateOp
  49. %token <ival>    NewplaneOp
  50. %token <cval>    DirOp
  51. %token <ival>    ConstOp
  52. %token <ival>    LineOp
  53. %token <ival>    AirportOp
  54. %token <ival>    BeaconOp
  55. %token <ival>    ExitOp
  56. %union {
  57.     int    ival;
  58.     char    cval;
  59. }
  60.  
  61. %{
  62. #include "include.h"
  63.  
  64. #ifndef lint
  65. static char sccsid[] = "@(#)grammar.y    5.2 (Berkeley) 4/30/90";
  66. #endif /* not lint */
  67.  
  68. int    errors = 0;
  69. int    line = 1;
  70. %}
  71.  
  72. %%
  73. file:
  74.     bunch_of_defs { if (checkdefs() < 0) return (errors); } bunch_of_lines
  75.         { 
  76.         if (sp->num_exits + sp->num_airports < 2)
  77.             yyerror("Need at least 2 airports and/or exits.");
  78.         return (errors);
  79.         }
  80.     ;
  81.  
  82. bunch_of_defs:
  83.     def bunch_of_defs
  84.     | def
  85.     ;
  86.  
  87. def:
  88.     udef
  89.     | ndef
  90.     | wdef
  91.     | hdef
  92.     ;
  93.  
  94. udef:
  95.     UpdateOp '=' ConstOp ';'
  96.         {
  97.         if (sp->update_secs != 0)
  98.             return (yyerror("Redefinition of 'update'."));
  99.         else if ($3 < 1)
  100.             return (yyerror("'update' is too small."));
  101.         else
  102.             sp->update_secs = $3;
  103.         }
  104.     ;
  105.  
  106. ndef:
  107.     NewplaneOp '=' ConstOp ';'
  108.         {
  109.         if (sp->newplane_time != 0)
  110.             return (yyerror("Redefinition of 'newplane'."));
  111.         else if ($3 < 1)
  112.             return (yyerror("'newplane' is too small."));
  113.         else
  114.             sp->newplane_time = $3;
  115.         }
  116.     ;
  117.  
  118. hdef:
  119.     HeightOp '=' ConstOp ';'
  120.         {
  121.         if (sp->height != 0)
  122.             return (yyerror("Redefinition of 'height'."));
  123.         else if ($3 < 3)
  124.             return (yyerror("'height' is too small."));
  125.         else
  126.             sp->height = $3; 
  127.         }
  128.     ;
  129.  
  130. wdef:
  131.     WidthOp '=' ConstOp ';'
  132.         {
  133.         if (sp->height != 0)
  134.             return (yyerror("Redefinition of 'width'."));
  135.         else if ($3 < 3)
  136.             return (yyerror("'width' is too small."));
  137.         else
  138.             sp->width = $3; 
  139.         }
  140.     ;
  141.  
  142. bunch_of_lines:
  143.     line bunch_of_lines
  144.         {}
  145.     | line
  146.         {}
  147.     ;
  148.  
  149. line:
  150.     BeaconOp ':' Bpoint_list ';'
  151.         {}
  152.     | ExitOp ':' Epoint_list ';'
  153.         {}
  154.     | LineOp ':' Lline_list ';'
  155.         {}
  156.     | AirportOp ':' Apoint_list ';'
  157.         {}
  158.     ;
  159.  
  160. Bpoint_list:
  161.     Bpoint Bpoint_list
  162.         {}
  163.     | Bpoint
  164.         {}
  165.     ;
  166.  
  167. Bpoint:
  168.     '(' ConstOp ConstOp ')'
  169.         {
  170.         if (sp->num_beacons % REALLOC == 0) {
  171.             if (sp->beacon == NULL)
  172.                 sp->beacon = (BEACON *) malloc((sp->num_beacons
  173.                     + REALLOC) * sizeof (BEACON));
  174.             else
  175.                 sp->beacon = (BEACON *) realloc(sp->beacon,
  176.                     (sp->num_beacons + REALLOC) * 
  177.                     sizeof (BEACON));
  178.             if (sp->beacon == NULL)
  179.                 return (yyerror("No memory available."));
  180.         }
  181.         sp->beacon[sp->num_beacons].x = $2;
  182.         sp->beacon[sp->num_beacons].y = $3;
  183.         check_point($2, $3);
  184.         sp->num_beacons++;
  185.         }
  186.     ;
  187.  
  188. Epoint_list:
  189.     Epoint Epoint_list
  190.         {}
  191.     | Epoint
  192.         {}
  193.     ;
  194.  
  195. Epoint:
  196.     '(' ConstOp ConstOp DirOp ')'
  197.         {
  198.         int    dir;
  199.  
  200.         if (sp->num_exits % REALLOC == 0) {
  201.             if (sp->exit == NULL)
  202.                 sp->exit = (EXIT *) malloc((sp->num_exits + 
  203.                     REALLOC) * sizeof (EXIT));
  204.             else
  205.                 sp->exit = (EXIT *) realloc(sp->exit,
  206.                     (sp->num_exits + REALLOC) * 
  207.                     sizeof (EXIT));
  208.             if (sp->exit == NULL)
  209.                 return (yyerror("No memory available."));
  210.         }
  211.         dir = dir_no($4);
  212.         sp->exit[sp->num_exits].x = $2;
  213.         sp->exit[sp->num_exits].y = $3;
  214.         sp->exit[sp->num_exits].dir = dir;
  215.         check_edge($2, $3);
  216.         check_edir($2, $3, dir);
  217.         sp->num_exits++;
  218.         }
  219.     ;
  220.  
  221. Apoint_list:
  222.     Apoint Apoint_list
  223.         {}
  224.     | Apoint
  225.         {}
  226.     ;
  227.  
  228. Apoint:
  229.     '(' ConstOp ConstOp DirOp ')'
  230.         {
  231.         int    dir;
  232.  
  233.         if (sp->num_airports % REALLOC == 0) {
  234.             if (sp->airport == NULL)
  235.                 sp->airport=(AIRPORT *)malloc((sp->num_airports
  236.                     + REALLOC) * sizeof(AIRPORT));
  237.             else
  238.                 sp->airport = (AIRPORT *) realloc(sp->airport,
  239.                     (sp->num_airports + REALLOC) * 
  240.                     sizeof(AIRPORT));
  241.             if (sp->airport == NULL)
  242.                 return (yyerror("No memory available."));
  243.         }
  244.         dir = dir_no($4);
  245.         sp->airport[sp->num_airports].x = $2;
  246.         sp->airport[sp->num_airports].y = $3;
  247.         sp->airport[sp->num_airports].dir = dir;
  248.         check_point($2, $3);
  249.         check_adir($2, $3, dir);
  250.         sp->num_airports++;
  251.         }
  252.     ;
  253.  
  254. Lline_list:
  255.     Lline Lline_list
  256.         {}
  257.     | Lline
  258.         {}
  259.     ;
  260.  
  261. Lline:
  262.     '[' '(' ConstOp ConstOp ')' '(' ConstOp ConstOp ')' ']'
  263.         {
  264.         if (sp->num_lines % REALLOC == 0) {
  265.             if (sp->line == NULL)
  266.                 sp->line = (LINE *) malloc((sp->num_lines + 
  267.                     REALLOC) * sizeof (LINE));
  268.             else
  269.                 sp->line = (LINE *) realloc(sp->line,
  270.                     (sp->num_lines + REALLOC) *
  271.                     sizeof (LINE));
  272.             if (sp->line == NULL)
  273.                 return (yyerror("No memory available."));
  274.         }
  275.         sp->line[sp->num_lines].p1.x = $3;
  276.         sp->line[sp->num_lines].p1.y = $4;
  277.         sp->line[sp->num_lines].p2.x = $7;
  278.         sp->line[sp->num_lines].p2.y = $8;
  279.         check_line($3, $4, $7, $8);
  280.         sp->num_lines++;
  281.         }
  282.     ;
  283. %%
  284.  
  285. check_edge(x, y)
  286. {
  287.     if (!(x == 0) && !(x == sp->width - 1) && 
  288.         !(y == 0) && !(y == sp->height - 1))
  289.         yyerror("edge value not on edge.");
  290. }
  291.  
  292. check_point(x, y)
  293. {
  294.     if (x < 1 || x >= sp->width - 1)
  295.         yyerror("X value out of range.");
  296.     if (y < 1 || y >= sp->height - 1)
  297.         yyerror("Y value out of range.");
  298. }
  299.  
  300. check_linepoint(x, y)
  301. {
  302.     if (x < 0 || x >= sp->width)
  303.         yyerror("X value out of range.");
  304.     if (y < 0 || y >= sp->height)
  305.         yyerror("Y value out of range.");
  306. }
  307.  
  308. check_line(x1, y1, x2, y2)
  309. {
  310.     int    d1, d2;
  311.  
  312.     check_linepoint(x1, y1);
  313.     check_linepoint(x2, y2);
  314.  
  315.     d1 = ABS(x2 - x1);
  316.     d2 = ABS(y2 - y1);
  317.  
  318.     if (!(d1 == d2) && !(d1 == 0) && !(d2 == 0))
  319.         yyerror("Bad line endpoints.");
  320. }
  321.  
  322. yyerror(s)
  323. {
  324.     fprintf(stderr, "\"%s\": line %d: %s\n", file, line, s);
  325.     errors++;
  326.  
  327.     return (errors);
  328. }
  329.  
  330. check_edir(x, y, dir)
  331. {
  332.     int    bad = 0;
  333.  
  334.     if (x == sp->width - 1)
  335.         x = 2;
  336.     else if (x != 0)
  337.         x = 1;
  338.     if (y == sp->height - 1)
  339.         y = 2;
  340.     else if (y != 0)
  341.         y = 1;
  342.     
  343.     switch (x * 10 + y) {
  344.     case 00: if (dir != 3) bad++; break;
  345.     case 01: if (dir < 1 || dir > 3) bad++; break;
  346.     case 02: if (dir != 1) bad++; break;
  347.     case 10: if (dir < 3 || dir > 5) bad++; break;
  348.     case 11: break;
  349.     case 12: if (dir > 1 && dir < 7) bad++; break;
  350.     case 20: if (dir != 5) bad++; break;
  351.     case 21: if (dir < 5) bad++; break;
  352.     case 22: if (dir != 7) bad++; break;
  353.     default:
  354.         yyerror("Unknown value in checkdir!  Get help!");
  355.         break;
  356.     }
  357.     if (bad)
  358.         yyerror("Bad direction for entrance at exit.");
  359. }
  360.  
  361. check_adir(x, y, dir)
  362. {
  363. }
  364.  
  365. checkdefs()
  366. {
  367.     int    err = 0;
  368.  
  369.     if (sp->width == 0) {
  370.         yyerror("'width' undefined.");
  371.         err++;
  372.     }
  373.     if (sp->height == 0) {
  374.         yyerror("'height' undefined.");
  375.         err++;
  376.     }
  377.     if (sp->update_secs == 0) {
  378.         yyerror("'update' undefined.");
  379.         err++;
  380.     }
  381.     if (sp->newplane_time == 0) {
  382.         yyerror("'newplane' undefined.");
  383.         err++;
  384.     }
  385.     if (err)
  386.         return (-1);
  387.     else
  388.         return (0);
  389. }
  390.